home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 726-750 / 741 / rkrm_lib1 / rkrm_lib1.lha / Intuition / Windows / lines.c < prev    next >
C/C++ Source or Header  |  1992-09-03  |  13KB  |  428 lines

  1. ;/* lines.c - Execute me to compile me with SAS C 5.10
  2. LC -b1 -cfistq -v -y -j73 lines.c
  3. Blink FROM LIB:c.o,lines.o TO lines LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. quit
  5. */
  6.  
  7. /*
  8. Copyright (c) 1992 Commodore-Amiga, Inc.
  9.  
  10. This example is provided in electronic form by Commodore-Amiga, Inc. for
  11. use with the "Amiga ROM Kernel Reference Manual: Libraries", 3rd Edition,
  12. published by Addison-Wesley (ISBN 0-201-56774-1).
  13.  
  14. The "Amiga ROM Kernel Reference Manual: Libraries" contains additional
  15. information on the correct usage of the techniques and operating system
  16. functions presented in these examples.  The source and executable code
  17. of these examples may only be distributed in free electronic form, via
  18. bulletin board or as part of a fully non-commercial and freely
  19. redistributable diskette.  Both the source and executable code (including
  20. comments) must be included, without modification, in any copy.  This
  21. example may not be published in printed form or distributed with any
  22. commercial product.  However, the programming techniques and support
  23. routines set forth in these examples may be used in the development
  24. of original executable software products for Commodore Amiga computers.
  25.  
  26. All other rights reserved.
  27.  
  28. This example is provided "as-is" and is subject to change; no
  29. warranties are made.  All use is at your own risk. No liability or
  30. responsibility is assumed.
  31. */
  32.  
  33.  
  34. /*
  35. ** lines.c -- implements a superbitmap with scroll gadgets
  36. ** This program requires V37, as it uses calls to OpenWindowTags(),
  37. ** LockPubScreen().
  38. */
  39.  
  40. /* Enforces use of new prefixed Intuition flag names */
  41. #define INTUI_V36_NAMES_ONLY
  42.  
  43. #include <exec/types.h>
  44. #include <exec/memory.h>
  45. #include <intuition/intuition.h>
  46.  
  47. #include <clib/exec_protos.h>
  48. #include <clib/layers_protos.h>
  49. #include <clib/graphics_protos.h>
  50. #include <clib/intuition_protos.h>
  51.  
  52. /* Random number function in amiga.lib (see amiga.lib.doc) */
  53. UWORD RangeRand( unsigned long maxValue );
  54.  
  55. #ifdef LATTICE
  56. int CXBRK(void)    { return(0); }  /* Disable Lattice CTRL/C handling */
  57. int chkabort(void) { return(0); }  /* really */
  58. #endif
  59.  
  60. #define WIDTH_SUPER     (800)
  61. #define HEIGHT_SUPER    (600)
  62.  
  63. #define UP_DOWN_GADGET    (0)
  64. #define LEFT_RIGHT_GADGET (1)
  65. #define NO_GADGET         (2)
  66.  
  67. #define MAXPROPVAL (0xFFFFL)
  68.  
  69. #define GADGETID(x) (((struct Gadget *)(msg->IAddress))->GadgetID)
  70.  
  71. #define LAYERXOFFSET(x) (x->RPort->Layer->Scroll_X)
  72. #define LAYERYOFFSET(x) (x->RPort->Layer->Scroll_Y)
  73.  
  74. /* A string with this format will be found by the version command
  75. ** supplied by Commodore.  This will allow users to give version
  76. ** numbers with error reports.
  77. */
  78. UBYTE vers[] = "$VER: lines 37.2";
  79.  
  80. struct Library *GfxBase;
  81. struct Library *IntuitionBase;
  82. struct Library *LayersBase;
  83.  
  84. struct Window      *Win = NULL;          /* window pointer */
  85. struct PropInfo     BotGadInfo = {0};
  86. struct Image        BotGadImage = {0};
  87. struct Gadget       BotGad = {0};
  88. struct PropInfo     SideGadInfo = {0};
  89. struct Image        SideGadImage = {0};
  90. struct Gadget       SideGad = {0};
  91.  
  92.  
  93. /* Prototypes for our functions */
  94. VOID initBorderProps(struct Screen *myscreen);
  95. VOID doNewSize(void);
  96. VOID doDrawStuff(void);
  97. VOID doMsgLoop(void);
  98. VOID superWindow(struct Screen *myscreen);
  99.  
  100.  
  101. /*
  102. ** main
  103. ** Open all required libraries and get a pointer to the default public screen.
  104. ** Cleanup when done or on error.
  105. */
  106. VOID main(int argc, char **argv)
  107. {
  108. struct Screen *myscreen;
  109.  
  110. /* open all of the required libraries for the program.
  111. **
  112. ** require version 37 of the Intuition library.
  113. */
  114.  
  115. if (IntuitionBase = OpenLibrary("intuition.library",37L))
  116.     {
  117.     if (GfxBase = OpenLibrary("graphics.library",33L))
  118.         {
  119.         if (LayersBase = OpenLibrary("layers.library",33L))
  120.             {
  121.             /* LockPubScreen()/UnlockPubScreen is only available under V36
  122.             ** and later... Use GetScreenData() under V34 systems to get a
  123.             ** copy of the screen structure...
  124.             */
  125.             if (NULL != (myscreen = LockPubScreen(NULL)))
  126.                 {
  127.                 superWindow(myscreen);
  128.                 UnlockPubScreen(NULL,myscreen);
  129.                 }
  130.             CloseLibrary(LayersBase);
  131.             }
  132.         CloseLibrary(GfxBase);
  133.         }
  134.     CloseLibrary(IntuitionBase);
  135.     }
  136. }
  137.  
  138.  
  139. /*
  140. ** Create, initialize and process the super bitmap window.
  141. ** Cleanup if any error.
  142. */
  143. VOID superWindow(struct Screen *myscreen)
  144. {
  145. struct BitMap *bigBitMap;
  146. WORD planeNum;
  147. WORD allocatedBitMaps;
  148.  
  149. /* set-up the border prop gadgets for the OpenWindow() call. */
  150. initBorderProps(myscreen);
  151.  
  152. /* The code relies on the allocation of the BitMap structure with
  153. ** the MEMF_CLEAR flag.  This allows the assumption that all of the
  154. ** bitmap pointers are NULL, except those successfully allocated
  155. ** by the program.
  156. */
  157. if (bigBitMap = AllocMem(sizeof(struct BitMap), MEMF_PUBLIC | MEMF_CLEAR))
  158.     {
  159.     InitBitMap(bigBitMap, myscreen->BitMap.Depth, WIDTH_SUPER, HEIGHT_SUPER);
  160.  
  161.     allocatedBitMaps = TRUE;
  162.     for (planeNum = 0;
  163.          (planeNum < myscreen->BitMap.Depth) && (allocatedBitMaps == TRUE);
  164.              planeNum++)
  165.         {
  166.         bigBitMap->Planes[planeNum] = AllocRaster(WIDTH_SUPER, HEIGHT_SUPER);
  167.         if (NULL == bigBitMap->Planes[planeNum])
  168.             allocatedBitMaps = FALSE;
  169.         }
  170.  
  171.     /* Only open the window if the bitplanes were successfully
  172.     ** allocated.  Fail silently if they were not.
  173.     */
  174.     if (TRUE == allocatedBitMaps)
  175.         {
  176.         /* OpenWindowTags() and OpenWindowTagList() are only available
  177.         ** when the library version is at least V36.  Under earlier
  178.         ** versions of Intuition, use OpenWindow() with a NewWindow
  179.         ** structure.
  180.         */
  181.         if (NULL != (Win = OpenWindowTags(NULL,
  182.                 WA_Width,  150,
  183.                 WA_Height, 4 * (myscreen->WBorTop + myscreen->Font->ta_YSize + 1),
  184.                 WA_MaxWidth,  WIDTH_SUPER,
  185.                 WA_MaxHeight, HEIGHT_SUPER,
  186.                 WA_IDCMP, IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  187.                     IDCMP_NEWSIZE | IDCMP_INTUITICKS | IDCMP_CLOSEWINDOW,
  188.                 WA_Flags, WFLG_SIZEGADGET | WFLG_SIZEBRIGHT | WFLG_SIZEBBOTTOM |
  189.                     WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
  190.                     WFLG_SUPER_BITMAP | WFLG_GIMMEZEROZERO | WFLG_NOCAREREFRESH,
  191.                 WA_Gadgets, &(SideGad),
  192.                 WA_Title, &vers[6], /* take title from version string */
  193.                 WA_PubScreen, myscreen,
  194.                 WA_SuperBitMap, bigBitMap,
  195.                 TAG_DONE)))
  196.             {
  197.             /* set-up the window display */
  198.             SetRast(Win->RPort,0); /* clear the bitplanes */
  199.             SetDrMd(Win->RPort,JAM1);
  200.  
  201.             doNewSize();    /* adjust props to represent portion visible */
  202.             doDrawStuff();
  203.  
  204.             /* process the window, return on IDCMP_CLOSEWINDOW */
  205.             doMsgLoop();
  206.  
  207.             CloseWindow(Win);
  208.             }
  209.         }
  210.  
  211.     for (planeNum = 0; planeNum < myscreen->BitMap.Depth; planeNum++)
  212.         {
  213.         /* free only the bitplanes actually allocated... */
  214.         if (NULL != bigBitMap->Planes[planeNum])
  215.             FreeRaster(bigBitMap->Planes[planeNum], WIDTH_SUPER, HEIGHT_SUPER);
  216.         }
  217.     FreeMem(bigBitMap,sizeof(struct BitMap));
  218.     }
  219. }
  220.  
  221. /*
  222. ** Set-up the prop gadgets--initialize them to values that fit
  223. ** into the window border.  The height of the prop gadget on the side
  224. ** of the window takes the height of the title bar into account in its
  225. ** set-up. note the initialization assumes a fixed size "sizing" gadget.
  226. **
  227. ** Note also, that the size of the sizing gadget is dependent on the
  228. ** screen resolution.  The numbers given here are only valid if the
  229. ** screen is NOT lo-res.  These values must be re-worked slightly
  230. ** for lo-res screens.
  231. **
  232. ** The PROPNEWLOOK flag is ignored by 1.3.
  233. */
  234. VOID initBorderProps(struct Screen *myscreen)
  235. {
  236. /* initializes the two prop gadgets.
  237. **
  238. ** Note where the PROPNEWLOOK flag goes.  Adding this flag requires
  239. ** no extra storage, but tells the system that our program is
  240. ** expecting the new-look prop gadgets under 2.0.
  241. */
  242. BotGadInfo.Flags     = AUTOKNOB | FREEHORIZ | PROPNEWLOOK;
  243. BotGadInfo.HorizPot  = 0;
  244. BotGadInfo.VertPot   = 0;
  245. BotGadInfo.HorizBody = -1;
  246. BotGadInfo.VertBody  = -1;
  247.  
  248. BotGad.LeftEdge     = 3;
  249. BotGad.TopEdge      = -7;
  250. BotGad.Width        = -23;
  251. BotGad.Height       = 6;
  252.  
  253. BotGad.Flags        = GFLG_RELBOTTOM | GFLG_RELWIDTH;
  254. BotGad.Activation   = GACT_RELVERIFY | GACT_IMMEDIATE | GACT_BOTTOMBORDER;
  255. BotGad.GadgetType   = GTYP_PROPGADGET | GTYP_GZZGADGET;
  256. BotGad.GadgetRender = (APTR)&(BotGadImage);
  257. BotGad.SpecialInfo  = (APTR)&(BotGadInfo);
  258. BotGad.GadgetID     = LEFT_RIGHT_GADGET;
  259.  
  260. SideGadInfo.Flags     = AUTOKNOB | FREEVERT | PROPNEWLOOK;
  261. SideGadInfo.HorizPot  = 0;
  262. SideGadInfo.VertPot   = 0;
  263. SideGadInfo.HorizBody = -1;
  264. SideGadInfo.VertBody  = -1;
  265.  
  266. /* NOTE the TopEdge adjustment for the border and the font for V36.
  267. */
  268. SideGad.LeftEdge   = -14;
  269. SideGad.TopEdge    = myscreen->WBorTop + myscreen->Font->ta_YSize + 2;
  270. SideGad.Width      = 12;
  271. SideGad.Height     = -SideGad.TopEdge - 11;
  272.  
  273. SideGad.Flags        = GFLG_RELRIGHT | GFLG_RELHEIGHT;
  274. SideGad.Activation   = GACT_RELVERIFY | GACT_IMMEDIATE | GACT_RIGHTBORDER;
  275. SideGad.GadgetType   = GTYP_PROPGADGET | GTYP_GZZGADGET;
  276. SideGad.GadgetRender = (APTR)&(SideGadImage);
  277. SideGad.SpecialInfo  = (APTR)&(SideGadInfo);
  278. SideGad.GadgetID     = UP_DOWN_GADGET;
  279. SideGad.NextGadget   = &(BotGad);
  280. }
  281.  
  282.  
  283. /*
  284. ** This function does all the work of drawing the lines
  285. */
  286. VOID doDrawStuff()
  287. {
  288. WORD x1,y1,x2,y2;
  289. WORD pen,ncolors,deltx,delty;
  290.  
  291. ncolors = 1 << Win->WScreen->BitMap.Depth;
  292. deltx = RangeRand(6)+2;
  293. delty = RangeRand(6)+2;
  294.  
  295. pen = RangeRand(ncolors-1) + 1;
  296. SetAPen(Win->RPort,pen);
  297. for(x1=0, y1=0, x2=WIDTH_SUPER-1, y2=HEIGHT_SUPER-1;
  298.         x1 < WIDTH_SUPER;
  299.                 x1 += deltx, x2 -= deltx)
  300.     {
  301.     Move(Win->RPort,x1,y1);
  302.     Draw(Win->RPort,x2,y2);
  303.     }
  304.  
  305. pen = RangeRand(ncolors-1) + 1;
  306. SetAPen(Win->RPort,pen);
  307. for(x1=0, y1=0, x2=WIDTH_SUPER-1, y2=HEIGHT_SUPER-1;
  308.         y1 < HEIGHT_SUPER;
  309.                 y1 += delty, y2 -= delty)
  310.     {
  311.     Move(Win->RPort,x1,y1);
  312.     Draw(Win->RPort,x2,y2);
  313.     }
  314. }
  315.  
  316. /*
  317. ** This function provides a simple interface to ScrollLayer
  318. */
  319. VOID slideBitMap(WORD Dx,WORD Dy)
  320. {
  321. ScrollLayer(0,Win->RPort->Layer,Dx,Dy);
  322. }
  323.  
  324. /*
  325. ** Update the prop gadgets and bitmap positioning when the size changes.
  326. */
  327. VOID doNewSize()
  328. {
  329. ULONG tmp;
  330.  
  331. tmp = LAYERXOFFSET(Win) + Win->GZZWidth;
  332. if (tmp >= WIDTH_SUPER)
  333.     slideBitMap(WIDTH_SUPER-tmp,0);
  334.  
  335. NewModifyProp(&(BotGad),Win,NULL,AUTOKNOB | FREEHORIZ,
  336.     ((LAYERXOFFSET(Win) * MAXPROPVAL) /
  337.         (WIDTH_SUPER - Win->GZZWidth)),
  338.     NULL,
  339.     ((Win->GZZWidth * MAXPROPVAL) / WIDTH_SUPER),
  340.     MAXPROPVAL,
  341.     1);
  342.  
  343. tmp = LAYERYOFFSET(Win) + Win->GZZHeight;
  344. if (tmp >= HEIGHT_SUPER)
  345.     slideBitMap(0,HEIGHT_SUPER-tmp);
  346.  
  347. NewModifyProp(&(SideGad),Win,NULL,AUTOKNOB | FREEVERT,
  348.     NULL,
  349.     ((LAYERYOFFSET(Win) * MAXPROPVAL) /
  350.         (HEIGHT_SUPER - Win->GZZHeight)),
  351.     MAXPROPVAL,
  352.     ((Win->GZZHeight * MAXPROPVAL) / HEIGHT_SUPER),
  353.     1);
  354. }
  355.  
  356. /*
  357. ** Process the currently selected gadget.
  358. ** This is called from IDCMP_INTUITICKS and when the gadget is released
  359. ** IDCMP_GADGETUP.
  360. */
  361. VOID checkGadget(UWORD gadgetID)
  362. {
  363. ULONG tmp;
  364. WORD dX = 0;
  365. WORD dY = 0;
  366.  
  367. switch (gadgetID)
  368.     {
  369.     case UP_DOWN_GADGET:
  370.         tmp = HEIGHT_SUPER - Win->GZZHeight;
  371.         tmp = tmp * SideGadInfo.VertPot;
  372.         tmp = tmp / MAXPROPVAL;
  373.         dY = tmp - LAYERYOFFSET(Win);
  374.         break;
  375.     case LEFT_RIGHT_GADGET:
  376.         tmp = WIDTH_SUPER - Win->GZZWidth;
  377.         tmp = tmp * BotGadInfo.HorizPot;
  378.         tmp = tmp / MAXPROPVAL;
  379.         dX = tmp - LAYERXOFFSET(Win);
  380.         break;
  381.     }
  382. if (dX || dY)
  383.     slideBitMap(dX,dY);
  384. }
  385.  
  386. /*
  387. ** Main message loop for the window.
  388. */
  389. VOID doMsgLoop()
  390. {
  391. struct IntuiMessage *msg;
  392. WORD flag = TRUE;
  393. UWORD currentGadget = NO_GADGET;
  394.  
  395. while (flag)
  396.     {
  397.     /* Whenever you want to wait on just one message port */
  398.     /* you can use WaitPort(). WaitPort() doesn't require */
  399.     /* the setting of a signal bit. The only argument it  */
  400.     /* requires is the pointer to the window's UserPort   */
  401.     WaitPort(Win->UserPort);
  402.     while (msg = (struct IntuiMessage *)GetMsg(Win->UserPort))
  403.         {
  404.         switch (msg->Class)
  405.             {
  406.             case IDCMP_CLOSEWINDOW:
  407.                 flag = FALSE;
  408.                 break;
  409.             case IDCMP_NEWSIZE:
  410.                 doNewSize();
  411.                 doDrawStuff();
  412.                 break;
  413.             case IDCMP_GADGETDOWN:
  414.                 currentGadget = GADGETID(msg);
  415.                 break;
  416.             case IDCMP_GADGETUP:
  417.                 checkGadget(currentGadget);
  418.                 currentGadget = NO_GADGET;
  419.                 break;
  420.             case IDCMP_INTUITICKS:
  421.                 checkGadget(currentGadget);
  422.                 break;
  423.             }
  424.         ReplyMsg((struct Message *)msg);
  425.         }
  426.     }
  427. }
  428.